package tuding.android.bigplanettracks.imageupload;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import tuding.android.bigplanettracks.R;
import android.app.Activity;
import android.app.Dialog;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.MediaStore.Images.Media;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;

public class ImageUploaderActivity extends Activity {
    public static String LOC_DATA = "loc.data";
    public final static int GALLERY = 40;// Source is gallery
    public final static int CAMERA = 41;// source is camera
    private static final int CAMERA_IMAGE_CAPTURE = 0;
    public Activity context;
    private ContentResolver mContentResolver;
    private final static String TAG="ImageUploaderActivity";
    private Bitmap mBitmap;
    //private ImageUploader mImageUploader;
    private Dialog chooserDialog;
    private File imageDir;//the dir to store the fullsize images processed in size to feed the tuding app
    private File thumbDir;//the dir to store thumb nail for the image
    //the directory for the tuding image storage
    private String imageDirPath;
    //the directory for the thumb images
    private String thumbDirPath;
    //the photo chosen as the preview
    private String currentPhoto;
    /**
     * Full size image slightly compressed to upload
     */
    private final int IMAGE_MAX_SIZE = 1024;
    /**
     * The thumbnail image used to for cellphone use
     */
    private final static int THUMBNAIL_SIZE=60;
    //the key for the comment of the picture chosen
    public static final String IMAGE_COMMENT="image.comment";
    public static final String IMAGE_NAME="image.name";
  //the key for the title of the picture chosen
    public static final String IMAGE_TITLE="image.title";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
         // Find the dir to save cached images
        if (android.os.Environment.getExternalStorageState().equals(
                android.os.Environment.MEDIA_MOUNTED))
            imageDir = new File(android.os.Environment
                    .getExternalStorageDirectory(), "tuding/photo/");
        else
            imageDir = context.getCacheDir();
        if (!imageDir.exists())
            imageDir.mkdirs();
        String path = imageDir.getAbsolutePath();
        thumbDir = new File(path+"/thumbnail/");
        if(!thumbDir.exists()) {
            thumbDir.mkdirs();
        }
        imageDirPath = imageDir.getAbsolutePath()+"/";
        thumbDirPath = thumbDir.getAbsoluteFile()+"/";
        mContentResolver = getContentResolver();
        //mImageUploader = new ImageUploader(this.getApplicationContext());
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        //Intent intent = this.getIntent();
        context = this;
        //Serializable loc = intent.getSerializableExtra(LOC_DATA);
        final Dialog dialog = new Dialog(this){

            @Override
            public void onBackPressed() {
                context.finish();
                super.onBackPressed();
            }
            
        };
        dialog.setContentView(R.layout.picselect);
        dialog.setTitle(R.string.CAMERA_OR_GALLERY);
        dialog.setCancelable(true);
        View camera = dialog.findViewById(R.id.launch_camera);
        camera.setOnClickListener(new OnClickListener() {
            @Override
            // choose to take photos
            public void onClick(View v) {
                try {
                    Intent i = new Intent("android.media.action.IMAGE_CAPTURE");
                    ContentValues values = new ContentValues();
                    values.put(Media.TITLE, "tudingimage");
                    values.put(Media.DESCRIPTION, "image captured by intent for tuding");
                    getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values);
                    currentPhoto = System.currentTimeMillis()+".jpg";
                    i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(imageDirPath+currentPhoto)));                      
                    startActivityForResult(i, CAMERA_IMAGE_CAPTURE);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                dialog.dismiss();

            }
        });
        View gallery = dialog.findViewById(R.id.launch_photo_gallery);
        gallery.setOnClickListener(new OnClickListener() {
            @Override
            // choose to take photos
            public void onClick(View v) {
                Intent intent = new Intent();
                intent = new Intent(
                        Intent.ACTION_PICK,
                        android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                ((Activity) context).startActivityForResult(
                        Intent.createChooser(intent, "Gallery"), GALLERY);
                dialog.dismiss();
            }
        });
        dialog.show();
        chooserDialog = dialog;
        
    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        //ugly that result code is not OK for the defalt return value from camera module, so don't put it inside the result check.
        File f =null;
        if(requestCode ==CAMERA_IMAGE_CAPTURE) {
            f = new File(imageDirPath+currentPhoto);
            if(!f.exists()) {
                chooserDialog.show();
                return;
            }
        }else if(resultCode!=RESULT_OK||data==null) {
            chooserDialog.show();
            return;
        }
        this.setContentView(R.layout.imgupload);
        final ImageView imgview = (ImageView) this.findViewById(R.id.uploadedimg);
        View overlay = (View) findViewById(R.id.overlay);
        int opacity = 100; // from 0 to 255
        overlay.setBackgroundColor(opacity * 0x222222); // black with a variable alpha
        FrameLayout.LayoutParams params =
            new FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT, FrameLayout.LayoutParams.FILL_PARENT);
        params.gravity = Gravity.BOTTOM;
        overlay.setLayoutParams(params);
        overlay.invalidate(); // update the view
        
        switch (requestCode) {
        case CAMERA_IMAGE_CAPTURE:
            Uri image = Uri.fromFile(f);
            imgview.setImageURI(image);
            mBitmap = getBitmap(image);
            break;
        case GALLERY:
            Uri selectedImg = null;
            selectedImg = data.getData();
            if(selectedImg==null) {
                return;
            }
            imgview.setImageURI(selectedImg);
            mBitmap = getBitmap(selectedImg);
            break;
        default:
            break;
        }
        final Button rotate = (Button) this.findViewById(R.id.rotate_btn);
        rotate.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View v) {
                mBitmap = rotateImage(mBitmap,90);
                imgview.setImageBitmap(mBitmap);
                
            }});
        final Button upload = (Button) this.findViewById(R.id.imgupload_submit);
        upload.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View v) {
                //store the processed image to the tuding gallery folder and return the uri for use
            	String photoname = System.currentTimeMillis()+".jpg";
                Uri uri = writeBitmapToStorage(mBitmap,photoname);
                // remove the capture photo
                if(currentPhoto != null) {
                	File ft = new File(imageDirPath+currentPhoto);
                	ft.delete();
                }
                Intent intent = new Intent();
                String comment =((EditText)findViewById(R.id.img_upload_comment)).getText().toString();
                //String title =((EditText)findViewById(R.id.img_upload_title)).getText().toString();
                intent.putExtra(IMAGE_COMMENT, comment);
                //intent.putExtra(IMAGE_TITLE, title);
                intent.putExtra(IMAGE_NAME, photoname);;
                setResult(RESULT_OK,intent);
                Log.i("IMAGE", "uri: "+uri.toString());
                //mImageUploader.uploadImg(uri, null, null);
                finish();
            }});
        

    }
    private Uri writeBitmapToStorage(Bitmap bitmap,String filename) {
        try {
            if(bitmap==null) {
                return null;
            }
            OutputStream fOut = null;
            File file = new File(imageDir, filename);
            fOut = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 75, fOut);
            fOut.flush();
            fOut.close();
            //making the thumbnail, for example if the file name is today.jpg, the thumbnail will be thumbnailtoday.jpg and it is stored in thumbnail dir
            //new Thread(new ThumbnailMaker(file,thumbDirPath+"thumbnail"+filename)).start();
            ThumbnailMaker(file, thumbDirPath+"thumbnail"+filename);
            Uri uri = Uri.fromFile(file);
            return uri;
        }catch(Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    
    //added for rotate
    public static Bitmap rotateImage(Bitmap src, float degree) {
        // create new matrix
        Matrix matrix = new Matrix();
        // setup rotation degree
        matrix.postRotate(degree);
        Bitmap bmp = Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, true);
        return bmp;
    }
    /*
    private Bitmap getBitmapFromPath(String path) {
        if(path==null) {
            return null;
        }
        Uri uri = getImageUri(path);
        return getBitmap(uri);
    }*/
    
    
    /**
     * Get the bitmap of the uri specified and this bitmap is compressed acroding to the size limit
     * @param uri uri for the image to be processed
     * @return the compressed image bitmap
     */
    private Bitmap getBitmap(Uri uri) {
        InputStream in = null;
        try {
            in = mContentResolver.openInputStream(uri);
            
            //Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            
            BitmapFactory.decodeStream(in, null, o);
            in.close();
            
            int scale = 1;
            if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
                scale = (int) Math.pow(2, (int) Math.round(Math
                        .log(IMAGE_MAX_SIZE
                                / (double) Math.max(o.outHeight, o.outWidth))
                        / Math.log(0.5)));
            }
            
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            in = mContentResolver.openInputStream(uri);
            Bitmap b = BitmapFactory.decodeStream(in, null, o2);
            in.close();
            
            return b;
        } catch (FileNotFoundException e) {
            Log.e(TAG, "file " +  " not found");
        } catch (IOException e) {
            Log.e(TAG, "file " + " not found");
        }
        return null;
    }
    
    
    /**
     * Compress the image to the tuding thumbnail dir
     * @param f the file to compress
     * @param size the dimension of the  image to compress to
     * @param thumbnailName the desired name of the thumbnail image
     * @return
     */
    private Bitmap compressFile(File f,int size,String thumbnailName) {
        Bitmap bitmap = null;
        
        FileInputStream is = null;
        
        try {
            // decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            is = new FileInputStream(f);
            BitmapFactory.decodeStream(is, null, o);
            is.close();
            is = null;
            
            // Find the correct scale value. It should be the power of 2.
            int scale = 1;
            if (size != 0) {
                final int REQUIRED_SIZE = size;
                int width_tmp = o.outWidth, height_tmp = o.outHeight;
                
                while (true) {
                    if (width_tmp / 2 < REQUIRED_SIZE
                            || height_tmp / 2 < REQUIRED_SIZE)
                        break;
                    width_tmp /= 2;
                    height_tmp /= 2;
                    scale *= 2;
                }
            }
            
            // decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            o2.inDensity = DisplayMetrics.DENSITY_MEDIUM;
            is = new FileInputStream(f);
            bitmap = BitmapFactory.decodeStream(is, null, o2);
            try {
                FileOutputStream out = new FileOutputStream(thumbnailName);
                bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
         } catch (Exception e) {
                e.printStackTrace();
         }
            
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                }
                is = null;
            }
        }
        
        return bitmap;
    }
    /*
    private Uri getImageUri(String path) {
        return Uri.fromFile(new File(path));
    }*/
    
    /**
     * This class process the fullsize image to produce the thumbnail good in size for us to use.
     *
     */
    /* thread is not good for preview
    private class ThumbnailMaker implements Runnable {
        private File  m_file;
        private String m_thumbnailName;
        public ThumbnailMaker(File uri,String thumbnailName) {
            this.m_file = uri;
            this.m_thumbnailName= thumbnailName;
        }

        @Override
        public void run() {
            try {
                if(m_file==null) {
                    return ;
                }
                // compress the file to the sdcard
                compressFile(m_file,THUMBNAIL_SIZE,m_thumbnailName);
            }catch(Exception e) {
                e.printStackTrace();
            }
            
        }
        
    }
    */
    private void ThumbnailMaker(File uri, String thumbnailName) {
    	try{
    		if(uri == null) return;
    		compressFile(uri, THUMBNAIL_SIZE, thumbnailName);
    	} catch(Exception e) {
    		e.printStackTrace();
    	}
    }
    
 
}
